package com.common.utils.http;

import java.io.File;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.StringPart;
import org.apache.commons.httpclient.params.HttpClientParams;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.commons.httpclient.params.HttpMethodParams;

/**
 * 
 * @author feijinbo
 * @creatTime 2011-7-5下午02:57:35
 * @desc http同步调用,接口参数不可为空，由调用程序自行校验.
 */
public class SyncHttpClient {

	private MultiThreadedHttpConnectionManager connectionManager;

	private HttpClient httpClient = null;

	public SyncHttpClient() {
		// change timeout to 2s avoid block thread-pool (Tim)
		this(150, 2000, 2000, 1024 * 1024);
	}

	public SyncHttpClient(int maxConPerHost, int conTimeOutMs, int soTimeOutMs,
			int maxSize) {
		connectionManager = new MultiThreadedHttpConnectionManager();
		HttpConnectionManagerParams params = connectionManager.getParams();
		params.setDefaultMaxConnectionsPerHost(maxConPerHost);
		params.setConnectionTimeout(conTimeOutMs);
		params.setSoTimeout(soTimeOutMs);
		HttpClientParams clientParams = new HttpClientParams();
		clientParams.setCookiePolicy(CookiePolicy.IGNORE_COOKIES);
		httpClient = new HttpClient(clientParams, connectionManager);

	}

	// 超时等待
	private static final int CONNECTION_TIMEOUT = 5000;

	// 字符集
	private static final String CONTENT_CHARSET = "UTF-8";

	/**
	 * Using GET method.
	 * 
	 * @param url
	 *            The remote URL.
	 * @param queryString
	 *            The query string containing parameters
	 * @return Response string.
	 * @throws Exception
	 */
	public String httpGet(String url, String queryString) throws Exception {
		String responseData = null;
		if (queryString != null && !queryString.equals("")) {
			url += "?" + queryString;
		}
		HttpClient httpClient = new HttpClient();
		GetMethod httpGet = new GetMethod(url);
		httpGet.getParams().setParameter("http.socket.timeout",
				new Integer(CONNECTION_TIMEOUT));
		try {
			int statusCode = httpClient.executeMethod(httpGet);
			if (statusCode != HttpStatus.SC_OK) {
				System.err.println("HttpGet Method failed: "
						+ httpGet.getStatusLine());
			}
			// Read the response body.
			responseData = httpGet.getResponseBodyAsString();
		} catch (Exception e) {
			throw new Exception(e);
		} finally {
			httpGet.releaseConnection();
			httpClient = null;
		}
		return responseData;
	}

	/**
	 * Using POST method.
	 * 
	 * @param url
	 *            The remote URL.
	 * @param queryString
	 *            The query string containing parameters
	 * @return Response string.
	 * @throws Exception
	 */
	public String httpPost(String url, String queryString) throws Exception {
		String responseData = null;
		HttpClient httpClient = new HttpClient();
		PostMethod httpPost = new PostMethod(url);
		// 设置超时
		httpPost.getParams().setParameter("http.socket.timeout",
				new Integer(CONNECTION_TIMEOUT));
		// 设置字符集
		httpPost.addRequestHeader("Content-Type", "text/html; charset=gbk");
		if (queryString != null && !queryString.equals("")) {
			httpPost.setRequestEntity(new ByteArrayRequestEntity(queryString
					.getBytes()));
		}
		try {
			int statusCode = httpClient.executeMethod(httpPost);
			if (statusCode != HttpStatus.SC_OK) {
				System.err.println("HttpPost Method failed: "
						+ httpPost.getStatusLine());
			}
			// Read the response body.
			responseData = httpPost.getResponseBodyAsString();
		} catch (Exception e) {
			throw new Exception(e);
		} finally {
			httpPost.releaseConnection();
			httpClient = null;
		}
		return responseData;
	}

	/**
	 * post by pairs
	 * 
	 * @param url
	 * @param pairs
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("rawtypes")
	public String httpPost(String url, List parameters) throws Exception {
		String responseData = null;
		// HttpClient httpClient = new HttpClient();
		PostMethod httpPost = new PostMethod(url);
		// 设置超时
		httpPost.getParams().setParameter("http.socket.timeout",
				new Integer(CONNECTION_TIMEOUT));
		// 设置字符集
		httpPost.getParams().setParameter(
				HttpMethodParams.HTTP_CONTENT_CHARSET, CONTENT_CHARSET);
		// 添加参数
		for (Iterator iter = parameters.iterator(); iter.hasNext();) {
			Parameter para = (Parameter) iter.next();
			httpPost.addParameter(para.mName == null ? "" : para.mName,
					para.mValue == null ? "" : para.mValue);
		}
		try {
			int statusCode = httpClient.executeMethod(httpPost);
			if (statusCode != HttpStatus.SC_OK) {
				System.err.println("HttpPost Method failed: "
						+ httpPost.getStatusLine());
			}
			// Read the response body.
			responseData = httpPost.getResponseBodyAsString();
		} catch (Exception e) {
			throw new Exception(e);
		} finally {
			httpPost.releaseConnection();
			httpClient = null;
		}

		return responseData;
	}

	/**
	 * Using POST method with multiParts.
	 * 
	 * @param url
	 *            the request url.
	 * @param params
	 * @param fileName
	 *            must provide
	 * @param file
	 * @return
	 * @throws Exception
	 */
//	public String httpPostWithFile(String url, List<Parameter> params,
//			String fileParamName, File file) throws Exception {
//		String responseData = null;
//		HttpClient httpClient = new HttpClient();
//		PostMethod httpPost = new PostMethod(url);
//		try {
//			int length = params.size()
//					+ (file != null && file.isFile() ? 1 : 0);
//			Part[] parts = new Part[length];
//			int i = 0;
//			for (Parameter entry : params) {
//				parts[i++] = new StringPart(entry.mName, entry.mValue,
//						CONTENT_CHARSET);
//			}
//			// 添加文件实体
//			if (file != null && file.isFile()) {
//				MyFilePart filePart = new MyFilePart(fileParamName,
//						file.getName(), file,
//						new MimetypesFileTypeMap().getContentType(file),
//						CONTENT_CHARSET);
//				filePart.setTransferEncoding("binary");
//				parts[i++] = filePart;
//			}
//			// 设置重试次数
//			httpPost.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
//					new DefaultHttpMethodRetryHandler(3, false));
//			httpPost.setRequestEntity(new MultipartRequestEntity(parts,
//					httpPost.getParams()));
//			int statusCode = httpClient.executeMethod(httpPost);
//			if (statusCode != HttpStatus.SC_OK) {
//				System.err.println("HttpPost Method failed: "
//						+ httpPost.getStatusLine());
//			}
//			responseData = httpPost.getResponseBodyAsString();
//		} catch (Exception e) {
//			throw new Exception(e);
//		} finally {
//			httpPost.releaseConnection();
//			httpClient = null;
//		}
//		return responseData;
//	}

	/**
	 * Using POST method with byte file
	 * 
	 * @param url
	 * @param queryString
	 * @param byData
	 * @return
	 * @throws Exception
	 */

	public String httpPostByteFile(String url, String queryString, byte[] byData)
			throws Exception {
		String responseData = null;
		url += '?' + queryString;
		HttpClient httpClient = new HttpClient();
		PostMethod httpPost = new PostMethod(url);
		try {
			httpPost.setRequestEntity(new ByteArrayRequestEntity(byData));
			int statusCode = httpClient.executeMethod(httpPost);
			if (statusCode != HttpStatus.SC_OK) {
				System.err.println("HttpPost Method failed: "
						+ httpPost.getStatusLine());
			}
			responseData = httpPost.getResponseBodyAsString();
		} catch (Exception e) {
			throw new Exception(e);
		} finally {
			httpPost.releaseConnection();
			httpClient = null;
		}
		return responseData;
	}

	/**
	 * 上传资源文件，资源带封面
	 * 
	 * @param url
	 * @param params
	 * @param fileParamName
	 * @param file
	 * @param cover
	 * @return
	 * @throws Exception
	 */
	public String httpPostWithFile(String url, List<Parameter> params,
			String fileParamName, File file, byte[] cover) throws Exception {
		String responseData = null;
		HttpClient httpClient = new HttpClient();
		PostMethod httpPost = new PostMethod(url);
		try {
			int length = params.size()
					+ (file != null && file.isFile() ? 1 : 0)
					+ (cover != null && cover.length > 0 ? 1 : 0);
			Part[] parts = new Part[length];
			int i = 0;
			for (Parameter entry : params) {
				parts[i++] = new StringPart(entry.mName, entry.mValue,
						CONTENT_CHARSET);
			}
//			// 添加文件实体
//			if (file != null && file.isFile()) {
//				MyFilePart filePart = new MyFilePart(fileParamName,
//						file.getName(), file,
//						new MimetypesFileTypeMap().getContentType(file),
//						CONTENT_CHARSET);
//				filePart.setTransferEncoding("binary");
//				parts[i++] = filePart;
//			}
			// 添加封面
			if (cover != null && cover.length > 0) {
				parts[i++] = new ByteArrayPart(cover, "pk_cover", null);
			}
			httpPost.setRequestEntity(new MultipartRequestEntity(parts,
					httpPost.getParams()));
			int statusCode = httpClient.executeMethod(httpPost);
			if (statusCode != HttpStatus.SC_OK) {
				System.err.println("HttpPost Method failed: "
						+ httpPost.getStatusLine());
			}
			responseData = httpPost.getResponseBodyAsString();
		} catch (Exception e) {
			throw new Exception(e);
		} finally {
			httpPost.releaseConnection();
			httpClient = null;
		}
		return responseData;
	}
}
